/**
 * 项目名：五位一体化工安全信息平台
 * 日期：    2019-12-08 15:07:44
 * Copyright (c) 2015- joysuch-版权所有
 */

package com.joysuch.wwyt.bp.service.impl;

import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.joysuch.wwyt.api.basedata.service.BaseImageSyncService;
import com.joysuch.wwyt.bp.bean.contractor.BpContractorDto;
import com.joysuch.wwyt.bp.bean.contractor.BpContractorQueryBean;
import com.joysuch.wwyt.bp.bean.contractor.BpContractorStaffBean;
import com.joysuch.wwyt.bp.entity.contractor.BpContractorStaff;
import com.joysuch.wwyt.bp.entity.contractor.dsl.QBpContractorStaff;
import com.joysuch.wwyt.bp.enums.DataStateTypes;
import com.joysuch.wwyt.bp.repository.BpContractorDao;
import com.joysuch.wwyt.bp.repository.BpContractorStaffDao;
import com.joysuch.wwyt.bp.service.BpContractorStaffService;
import com.joysuch.wwyt.core.bean.*;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.DateTimeUtil;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.enums.BaseConfigCodes;
import com.joysuch.wwyt.core.enums.BaseIdCardTypes;
import com.joysuch.wwyt.core.service.*;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.edu.bean.EduCertIdNameDto;
import com.joysuch.wwyt.edu.bean.EduCertUserDto;
import com.joysuch.wwyt.edu.bean.EduCertUserQueryBean;
import com.joysuch.wwyt.edu.entity.EduCertificate;
import com.joysuch.wwyt.edu.repository.EduCertificateDao;
import com.joysuch.wwyt.edu.repository.EduCertificateUserDao;
import com.joysuch.wwyt.monitoringcenter.bean.SyncBatchDataReturnBean;
import com.joysuch.wwyt.monitoringcenter.service.LocateServerService;
import com.joysuch.wwyt.util.PageableUtil;
import com.joysuch.wwyt.util.SnowFlakeUtil;
import com.joysuch.wwyt.util.ZipUtil;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.Assert;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.Tuple;
import javax.validation.Valid;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class BpContractorStaffServiceImpl implements BpContractorStaffService {

    @Autowired
    private BpContractorStaffDao dao;
    @Autowired
    private BpContractorDao bpContractorDao;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;
    @Autowired
    private EduCertificateDao eduCertificateDao;
    @Autowired
    private BaseTypeGroupItemService baseTypeGroupItemService;
    @Autowired
    private LocateServerService locateServerService;
    @Autowired
    private BaseConfigService baseConfigService;
    @Autowired
    private EduCertificateUserDao eduCertificateUserDao;
    @Autowired
    private BaseUserService baseUserService;
    @Autowired
    private ZipProcessService zipProcessService;
    @Autowired
    private BaseImageRepositoryService baseImageRepositoryService;
    @Autowired
    private BaseImageSyncService baseImageSyncService;
    @Autowired
    private BaseRoleDataAuthService baseRoleDataAuthService;
    @Autowired
    private BpContractorStaffDao bpContractorStaffDao;

    @Override
    public ResultBean save(@Valid BpContractorStaffBean bean) {
        Long id = bean.getId();

        BpContractorStaff bpContractorStaff;
        if (id == null) {
            bpContractorStaff = new BpContractorStaff();
            bpContractorStaff.setCode(bizCodeGeneratorFacade.wailairenyuan());
            bpContractorStaff.setState(DataStateTypes.EFFECTIVE.getState());
        } else {
            bpContractorStaff = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("此数据不存在"));
        }
        BeanUtils.copyProperties(bean, bpContractorStaff, "code", "state");
        if (bpContractorStaff.getUniqueId() == null) {
            bpContractorStaff.setUniqueId(SnowFlakeUtil.getContractorStaffId());
        }
        BaseAttachmentBean idCardImg = bean.getIdCardImg();
        bpContractorStaff.setIdCardImgJson(idCardImg == null ? null : JSON.toJSONString(idCardImg));
        BaseAttachmentBean cap = bean.getCap();
        bpContractorStaff.setCapId(cap == null ? null : cap.getId());
        BpContractorStaff save = dao.save(bpContractorStaff);
        // 判断 定位卡 门禁卡号是否重复
        baseUserService.checkUser(save.getCardNumber(), save.getSn(), "staff");
        String locateVersion = locateServerService.getLocateVersion();
        if ("3.x".equals(locateVersion)) {
            if (isEmployeeSyncOpen()) {
                locateServerService.syncLocateUsers(Lists.newArrayList(save), 1);
            }
            return ResultBean.defaultSuccessResult();
        }
        // 4.x
        // 同步承包商人员
        if (isEmployeeSyncOpen()) {
            locateServerService.syncLocateUsers(Lists.newArrayList(save), 1);
        }
        return ResultBean.defaultSuccessResult();
    }

    @Override
    public ResultBean page(BpContractorQueryBean bean) {
        List<Tuple> list = dao.page(bean.getName(), bean.getContractorType(), bean.getContractorId(), bean.getSn() ,bean.getLocateSync());
        int totalSize = list.size();
        List<Tuple> resultList = PageableUtil.getList(bean.getPage(), bean.getSize(), list);
        List<BpContractorDto> dtoList = Lists.newArrayList();
        for (Tuple tuple : resultList) {
            BigInteger id = tuple.get("id", BigInteger.class);
            String code = tuple.get("code", String.class);
            String staffName = tuple.get("staffName", String.class);
            String contractorName = tuple.get("contractorName", String.class);
            String contractorType = tuple.get("contractorType", String.class);
            String refUrl = tuple.get("refUrl", String.class);
            BigInteger alarmTemplateId = tuple.get("alarmTemplateId", BigInteger.class);
            String alarmTemplateName = tuple.get("alarmTemplateName", String.class);
            Boolean locateSync = tuple.get("locateSync", Boolean.class);
            String sn = tuple.get("sn", String.class);
            String telPhone = tuple.get("telPhone", String.class);
            dtoList.add(new BpContractorDto(id, code, staffName, contractorName, contractorType, refUrl,
                    alarmTemplateId, alarmTemplateName, locateSync, sn,telPhone));
        }
        return ResultBean.pageData(dtoList, totalSize);
    }

    private boolean isEmployeeSyncOpen() {
        BaseConfig config = baseConfigService.findFirstConfig(BaseConfigCodes.LOCATE_SERVER_EMPLOYEE_SYNC_OPEN);
        return config == null ? false : "true".equalsIgnoreCase(config.getValue());
    }

    @Override
    public ResultBean get(Long id) {
        Assert.notNull(id, "id cannot be null");
        BpContractorStaff staff = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("此数据不存在"));
        if (DataStateTypes.UN_EFFECTIVE.getState().equals(staff.getState())) {
            return ResultBean.fail(101, "此数据已作废");
        }
        BpContractorStaffBean bpContractorStaffBean = new BpContractorStaffBean();
        BeanUtils.copyProperties(staff, bpContractorStaffBean);
        String idCardImgJson = staff.getIdCardImgJson();
        bpContractorStaffBean.setIdCardImg(
                idCardImgJson == null ? null : JSONObject.parseObject(idCardImgJson, BaseAttachmentBean.class));
        setData(staff, bpContractorStaffBean);
        BaseAttachmentBean idCardImageObj = JSONObject.parseObject(idCardImgJson, BaseAttachmentBean.class);
        if (StringUtils.isNotEmpty(bpContractorStaffBean.getFacePic())) {
            if (idCardImageObj == null) {
                idCardImageObj = new BaseAttachmentBean();
            }
            idCardImageObj.setDownloadUrl(bpContractorStaffBean.getFacePic());
            bpContractorStaffBean.setIdCardImg(idCardImageObj);
        } else {
            bpContractorStaffBean.setIdCardImg(idCardImgJson == null ? null : idCardImageObj);
        }
        BaseAttachmentBean cap = new BaseAttachmentBean();
        cap.setId(staff.getCapId());
        cap.setDownloadUrl("/image/view?id=" + staff.getCapId());
        bpContractorStaffBean.setCap(cap);
        return ResultBean.success(bpContractorStaffBean);
    }

    private void setData(BpContractorStaff staff, BpContractorStaffBean bpContractorStaffBean) {
        // 民族
        if (staff.getNation() != null) {
            bpContractorStaffBean.setNationName(baseTypeGroupItemService.findNameById(staff.getNation()));
        }
        // 身份
        if (staff.getIdentity() != null) {
            bpContractorStaffBean.setIdentityName(staff.getIdentity() == 1 ? "员工" : "管理人员");
        }
        // 承包商单位
        if (staff.getContractorId() != null) {
            bpContractorStaffBean.setContractorName(bpContractorDao.getOne(staff.getContractorId()).getCompanyName());
        }
        // 学历
        if (staff.getEducation() != null) {
            bpContractorStaffBean.setEducationName(baseTypeGroupItemService.findNameById(staff.getEducation()));
        }
        // 健康状况
        if (staff.getHealthStatus() != null) {
            bpContractorStaffBean.setHealthStatusName(baseTypeGroupItemService.findNameById(staff.getHealthStatus()));
        }
        // 证件类型
        if (staff.getIdCardType() != null) {
            bpContractorStaffBean.setIdCardTypeName(BaseIdCardTypes.getIdName(staff.getIdCardType().intValue()));
        }
    }

    @Override
    public BpContractorStaff getById(Long id) {
        return dao.findById(id).orElse(null);
    }

    @Override
    public ResultBean nullify(Long id) {
        Assert.notNull(id, "id cannot be null");
        BpContractorStaff staff = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("此数据不存在"));
        Integer state = staff.getState();
        if (DataStateTypes.UN_EFFECTIVE.getState().equals(state)) {
            return ResultBean.fail(101, "此数据已作废");
        }
        staff.setState(DataStateTypes.UN_EFFECTIVE.getState());
        BpContractorStaff save = dao.save(staff);

        // 证书模块：执证承包商人员被删除，相应执证记录也应删除
//        eduCertificateUserDao.deleteByUserIdAndUserContractorFlag(id, 1);

        // 同步承包商人员
        if (isEmployeeSyncOpen()) {
            locateServerService.syncLocateUsers(Lists.newArrayList(save), 1);
        }
        return ResultBean.defaultSuccessResult();
    }

    @Override
    public Page<BaseUserListBean> userModelPage(String name, Long contractorId, Pageable pageable) {
        // 只取合格承包商
        List<Tuple> tuples = dao.userModelPage(name, contractorId);
        List<Tuple> list = PageableUtil.getList(pageable, tuples);
        int totalSize = tuples.size();
        List<BaseUserListBean> resultList = Lists.newArrayList();
        for (Tuple tuple : list) {
            BigInteger id = tuple.get("id", BigInteger.class);
            String code = tuple.get("code", String.class);
            String staffName = tuple.get("name", String.class);
            String contractorName = tuple.get("contractorName", String.class);
            resultList.add(new BaseUserListBean(id.longValue(), code, staffName, contractorName, 1));
        }
        return new PageImpl<>(resultList, pageable, totalSize);
    }

    @Override
    public Page<BaseUserListBean> userModelWfPage(String nameOrCode, Long companyId, Long tenantId, String orgCode, Pageable page) {
        // 只取合格承包商
        List<Tuple> tuples = dao.userModelWfPage(nameOrCode, companyId, tenantId, orgCode);
        List<Tuple> list = PageableUtil.getList(page, tuples);
        int totalSize = tuples.size();
        List<BaseUserListBean> resultList = Lists.newArrayList();
        for (Tuple tuple : list) {
            BigInteger id = tuple.get("id", BigInteger.class);
            String code = tuple.get("code", String.class);
            String staffName = tuple.get("name", String.class);
            String contractorName = tuple.get("contractorName", String.class);
            resultList.add(new BaseUserListBean(id.longValue(), code, staffName, contractorName, 1));
        }
        return new PageImpl<>(resultList, page, totalSize);
    }

    @Override
    public List<SimpleUserBean> getAllContractorSimpleList() {
        // 只取合格承包商
        List<Tuple> tuples = dao.userModelPage(null, null);
        List<SimpleUserBean> resultList = Lists.newArrayList();
        for (Tuple tuple : tuples) {
            BigInteger id = tuple.get("id", BigInteger.class);
            String staffName = tuple.get("name", String.class);
            resultList.add(new SimpleUserBean(id.longValue(), staffName));
        }
        return resultList;
    }


    @Override
    public ResultBean getEduContractorUserCert(EduCertUserQueryBean bean, Pageable pageable) {
        List<EduCertUserDto> resultList = Lists.newArrayList();
        Long tenentId = Context.getCurrentTenantId();
        // String orgCode = Context.getCurrentOrgCode().substring(0, 7);
        String orgCode = Context.getCompanyCode();
        // 只取合格承包商
        // 无条件查询
        if (noQueryJudge(bean)) {
            List<Tuple> list = dao.getEduContractorUserCertNoQuery(tenentId, orgCode);
            return dataFurther(pageable, resultList, list, bean);
        }
        // 有certIdList
        else if (!CollectionUtils.isEmpty(bean.getCertIdList())) {
            // 去除过期证书
            LocalDateTime localDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.of(0, 0, 0));
            Date date = DateTimeUtil.localDateTime2Date(localDateTime);
            List<Tuple> list = dao.getEduContractorUserCertWithCertIds(bean.getEnterPrise(), bean.getName(),
                    bean.getCertIdList(), date);
            return dataFurther(pageable, resultList, list, bean);
        }
        // 无certIdList
        else {
            List<Tuple> list = dao.getEduContractorUserCert(bean.getEnterPrise(), bean.getName());
            return dataFurther(pageable, resultList, list, bean);
        }

    }

    @Override
    public String getNameById(Long id) {
        BpContractorStaff staff = dao.findById(id).orElse(null);
        return staff == null ? "" : staff.getName();
    }

    @Override
    public List<Long> getStaffIdByNameContains(String userName) {
        return dao.getStaffIdByNameContains(userName);
    }

    @Override
    public ResultBean locateSyncUser(Integer flag, List<Long> userIds) {
        Assert.isTrue(flag == 1 || flag == 0, "flag not permit");
        List<BpContractorStaff> list;
        if (flag == 1) {
            list = dao.findAll();
        } else {
            list = dao.findAllById(userIds);
        }
        locateServerService.syncLocateUsers(list, 1);
        return ResultBean.defaultSuccessResult();
    }

    private static final List<UserDataSourceDto> dataSourceDtoList = new ArrayList<>(20);

    static {
        dataSourceDtoList.add(new UserDataSourceDto("name", "姓名"));
        dataSourceDtoList.add(new UserDataSourceDto("oldName", "曾用名"));
        dataSourceDtoList.add(new UserDataSourceDto("roleName", "身份"));
        dataSourceDtoList.add(new UserDataSourceDto("contractorName", "承包商单位"));
        dataSourceDtoList.add(new UserDataSourceDto("sn", "定位卡号"));
        dataSourceDtoList.add(new UserDataSourceDto("nation", "民族"));
        dataSourceDtoList.add(new UserDataSourceDto("idCardNo", "证件号码"));
        dataSourceDtoList.add(new UserDataSourceDto("healthStatus", "健康状况"));
        dataSourceDtoList.add(new UserDataSourceDto("major", "专业"));
        dataSourceDtoList.add(new UserDataSourceDto("workAt", "从业所在地"));
        dataSourceDtoList.add(new UserDataSourceDto("postcode", "邮编"));
        dataSourceDtoList.add(new UserDataSourceDto("title", "职称/技能等级"));
        dataSourceDtoList.add(new UserDataSourceDto("gender", "性别"));
        dataSourceDtoList.add(new UserDataSourceDto("cardNumber", "门禁卡号"));
        dataSourceDtoList.add(new UserDataSourceDto("idCardType", "证件类型"));
        dataSourceDtoList.add(new UserDataSourceDto("telephone", "联系电话"));
        dataSourceDtoList.add(new UserDataSourceDto("education", "学历"));
        dataSourceDtoList.add(new UserDataSourceDto("censusRegister", "户籍所在地"));
        dataSourceDtoList.add(new UserDataSourceDto("address", "通讯地址"));
        dataSourceDtoList.add(new UserDataSourceDto("joinWorkDate", "参加工作时间"));
    }

    @Override
    public ResultBean getAllFields(Pageable pageable) {
        List<UserDataSourceDto> list = PageableUtil.getList(pageable, dataSourceDtoList);
        return ResultBean.pageData(new PageImpl(list, pageable, dataSourceDtoList.size()));
    }

    /**
     * 添加承包商人员报警模板
     *
     * @param staffId
     * @param templateId
     * @param templateName
     * @return
     */
    @Override
    public BpContractorStaff editAlarmTemplate(Long staffId, Long templateId, String templateName) {
        BpContractorStaff staff = dao.findById(staffId).orElseThrow(() -> new IllegalArgumentException("承包商人员不存在"));
        if (templateId != null && 0 != templateId){
            staff.setAlarmTemplateId(templateId);
            staff.setAlarmTemplateName(templateName);
        }else {
            staff.setAlarmTemplateId(null);
            staff.setAlarmTemplateName(null);
        }
        locateServerService.syncLocateUsers(Lists.newArrayList(staff), 1);
        BpContractorStaff save = dao.save(staff);
        return save;
    }

    @Override
    public ResultBean getIdBySn(String sn) {
        BpContractorStaff staff = dao.findOneBySn(sn);
        return ResultBean.success(staff == null ? null : staff.getId());
    }

    private ResultBean dataFurther(Pageable pageable, List<EduCertUserDto> resultList, List<Tuple> list,
                                   EduCertUserQueryBean bean) {
        if (!CollectionUtils.isEmpty(bean.getCertIdList()) && bean.getTypeFlag() != null && bean.getTypeFlag() == 1) {
            convertData(list, resultList);
            // 交集
            for (int i = 0; i < resultList.size(); i++) {
                List<EduCertIdNameDto> dtoList = resultList.get(i).getDtoList();
                List<Long> certIdList = dtoList.stream().map(r -> r.getCertId()).collect(Collectors.toList());
                if (!certIdList.containsAll(bean.getCertIdList())) {
                    resultList.remove(i);
                }
            }
            List<EduCertUserDto> returnList = PageableUtil.getList(pageable, resultList);
            return ResultBean.pageData(returnList, resultList.size());
        } else {
            int totalSize = list.size();
            convertData(list, resultList);
            // 去除非筛选的证书
            if (!CollectionUtils.isEmpty(bean.getCertIdList())) {
                for (EduCertUserDto dto : resultList) {
                    List<EduCertIdNameDto> dtoList = dto.getDtoList();
                    Iterator<EduCertIdNameDto> iterator = dtoList.iterator();
                    while (iterator.hasNext()) {
                        EduCertIdNameDto next = iterator.next();
                        if (!bean.getCertIdList().contains(next.getCertId())) {
                            iterator.remove();
                        }
                    }
                }
            }
            resultList = PageableUtil.getList(pageable, resultList);
            return ResultBean.pageData(resultList, totalSize);
        }
    }

    private void convertData(List<Tuple> list, List<EduCertUserDto> resultList) {
        for (Tuple tuple : list) {
            BigInteger userId = tuple.get("userId", BigInteger.class);
            String code = tuple.get("code", String.class);
            String userName = tuple.get("name", String.class);
            String companyName = tuple.get("companyName", String.class);
            // 去除过期证书
            LocalDateTime localDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.of(0, 0, 0));
            Date date = DateTimeUtil.localDateTime2Date(localDateTime);
            List<EduCertificate> eduCertificateList = eduCertificateDao.getCertByUserId(userId.longValue(), 1, date);
            // 一人多证
            Map<Long, Boolean> map = new ConcurrentHashMap<>((int) (eduCertificateList.size() / 0.75f + 1f));
            List<EduCertificate> collect = eduCertificateList.stream().filter(distinctById(r -> r.getId(), map))
                    .collect(Collectors.toList());
            List<EduCertIdNameDto> tempList = collect.stream().map(EduCertIdNameDto::new).collect(Collectors.toList());
            resultList.add(new EduCertUserDto(code, userName, companyName, userId, tempList));
        }
        Map<BigInteger, Boolean> tMap = new ConcurrentHashMap<>((int) (list.size() / 0.75f + 1f));
        Iterator<EduCertUserDto> iterator = resultList.iterator();
        while (iterator.hasNext()) {
            EduCertUserDto next = iterator.next();
            if (tMap.get(next.getUserId()) != null) {
                iterator.remove();
            } else {
                tMap.putIfAbsent(next.getUserId(), true);
            }
        }
    }

    // private boolean certIdJudge(EduCertUserQueryBean bean) {
    // return bean.getCertId() == null;
    // }

    private boolean noQueryJudge(EduCertUserQueryBean bean) {
        return bean.getName() == null && bean.getEnterPrise() == null && bean.getCertIdList() == null;
    }

    static <T> java.util.function.Predicate<T> distinctById(Function<? super T, ?> function, Map map) {
        return t -> map.putIfAbsent(function.apply(t), Boolean.TRUE) == null;
    }

    @Override
    public BatchUploadResult batchUploadIdImages(MultipartFile file, String type) {
        BatchUploadResult result = new BatchUploadResult();
        List<BatchUploadInfoBean> list = unzipAndParseUploadInfo(file, "UTF-8", "GBK");
        List<BatchUploadInfoBean> infos = list.stream().filter(f -> !f.isIgnored()).collect(Collectors.toList());
        if (infos.size() > 0) {
            boolean sync = baseConfigService.checkIfSync();
            List<String> certNos = infos.stream().map(BatchUploadInfoBean::getBaseName)
                    .collect(Collectors.toList());
            List<BpContractorStaff> users = findUserByType(certNos, type);
            cn.hutool.core.lang.UUID uuid = UUID.randomUUID();
            File newDir = new File(infos.get(0).getDirPath(), uuid.toString());
            newDir.mkdir();
            infos.forEach(e -> {
                Optional<BpContractorStaff> first = users.stream()
                        .filter(u -> userMatches(u, e.getBaseName(), type)).findFirst();
                if (first.isPresent()) {
                    if (sync) {
                        try {
                            zipProcessService.copyFile(e.getFile(), new File(newDir.getAbsolutePath(), first.get().getUniqueId() + "." + e.getSuffix()));
                        } catch (Exception ex) {
                            log.error(ex.getMessage(), ex);
                        }
                    }
                    first.get().setFacePic(baseImageRepositoryService.generateImageUrlById(e.getId()));
                    dao.save(first.get());
                    result.setSucceedCount(result.getSucceedCount() + 1);
                } else {
                    result.setFailCount(result.getFailCount() + 1);
                    result.getFailItems().add(e.getFilename());
                }
            });
            //同步
            if (sync) {
                try {
                    ZipUtil.toZip(newDir, new FileOutputStream(newDir.getAbsolutePath() + File.separator + uuid.toString() + ".zip"), true);
                } catch (FileNotFoundException e) {
                    log.error(e.getMessage(), e);
                }
                this.syncUserHeanImage(newDir.getAbsolutePath() + File.separator + uuid.toString() + ".zip");
            }
            // 清理临时目录
            zipProcessService.deleteTempDir(infos.get(0).getTempDir());
        }
        list.forEach(f -> {
            if (f.isIgnored()) {
                result.getIgnoreItems().add(f.getFilename());
            }
        });
        return result;
    }

    @Override
    public void batchSyncData(List<BpContractorStaff> datas) {
        //去重 重复数据保留最后一个
        Map<Long, BpContractorStaff> syncMap = new LinkedHashMap();
        for (BpContractorStaff staff : datas) {
            syncMap.put(staff.getId(), staff);
        }
        List<Long> allIds = new ArrayList<>();
        Set<Map.Entry<Long, BpContractorStaff>> entryseSet = syncMap.entrySet();
        for (Map.Entry<Long, BpContractorStaff> entry : entryseSet) {
            allIds.add(entry.getKey());
        }
        List<BpContractorStaff> syncList = syncMap.values().stream().collect(toList());
        Map<String, BpContractorStaff> idMap = syncList.stream().collect(Collectors.toMap(r -> r.getUniqueId(), r -> r));
        List<Long> unSyncIds = new ArrayList<>();
        List<SyncBatchDataReturnBean> returnBeans = locateServerService.syncSaveStaff(syncList, locateServerService.getBuildId(), locateServerService.getLoginToken());
        if (!CollectionUtils.isEmpty(returnBeans)) {
            for (SyncBatchDataReturnBean bean : returnBeans) {
                if (idMap.get(bean.getUniqueId()) != null) {
                    unSyncIds.add(idMap.get(bean.getUniqueId()).getId());
                }
            }
        }
        if (!CollectionUtils.isEmpty(unSyncIds)) {
            allIds.removeAll(unSyncIds);
            dao.editLocateSyncByIds(unSyncIds, Integer.valueOf(0));
        }
        if (!CollectionUtils.isEmpty(allIds)) {
            dao.editLocateSyncByIds(allIds, Integer.valueOf(1));
        }
    }

    private void syncUserHeanImage(String path) {
        baseImageSyncService.batchPeopleHeadImages(path, locateServerService.getBuildId(), locateServerService.getLoginToken(), "staff");
    }

    private List<BatchUploadInfoBean> unzipAndParseUploadInfo(MultipartFile file, String... tryEncodings) {
        for (String encoding : tryEncodings) {
            try {
                List<BatchUploadInfoBean> infos = zipProcessService.batchUploadImages(file.getInputStream(), true, 1,
                        Charset.forName(encoding), "jpg", "jpeg", "png");
                return infos;
            } catch (Exception e) {
                log.error("解析{}出错，encoding={}", file.getOriginalFilename(), encoding, e);
            }
        }
        throw new RuntimeException("解析zip文件异常:file=" + file.getOriginalFilename());
    }

    private List<BpContractorStaff> findUserByType(List<String> certNos, String type) {
        Predicate p = null;
        QBpContractorStaff q = QBpContractorStaff.bpContractorStaff;
        if ("sn".equals(type)) {
            p = QBpContractorStaff.bpContractorStaff.sn.in(certNos);
        } else if ("name".equals(type)) {
            p = QBpContractorStaff.bpContractorStaff.name.in(certNos);
        } else if ("code".equals(type)) {
            p = QBpContractorStaff.bpContractorStaff.code.in(certNos);
        }

        p = ExpressionUtils.and(p, q.state.eq(DataStateTypes.EFFECTIVE.getState()).or(q.state.isNull()));

        return p == null ? Collections.EMPTY_LIST : (List) dao.findAll(p);
    }

    private boolean userMatches(BpContractorStaff u, String baseName, String type) {
        if ("sn".equals(type)) {
            return baseName.equals(u.getSn());
        }
        if ("name".equals(type)) {
            return baseName.equals(u.getName());
        }
        if ("code".equals(type)) {
            return baseName.equals(u.getCode());
        }
        return false;
    }

    @Override
    public Set<Long> findStaffIds() {
        Set<Long> staffIds = new HashSet<>();
        Set<Long> authDepartIds = baseRoleDataAuthService.findAuthDepartIdsByCurUser();
        //查询角色部门列表管理的承包商
        Set<Long> contractorIds = bpContractorDao.findAllContractorIdsByDepartIds(authDepartIds);
        //查询承包商下面所有的人员
        if (!CollectionUtils.isEmpty(contractorIds)) {
            staffIds = bpContractorStaffDao.findStaffIdsByContractorIds(contractorIds);
        }
        return staffIds;
    }
}
